﻿#region References
using System;
using System.Windows.Forms;
using System.Net;
using System.IO;
using System.Globalization;
using System.Xml;
using System.Collections.Generic;
#endregion

namespace Autumoon.OpenSource.TScreenSaver.Forms
{
    public partial class ScreenSaverForm : Form
    {
        #region Fields and Properties
        private Timer _contentTimer;
        private Timer _presentationTimer;
        private int _presentationTime;

        private static ScreenSaverForm _instance;
        public static ScreenSaverForm Instance
        {
            get { return ((_instance == null || _instance.IsDisposed) ? _instance = new ScreenSaverForm() : _instance); }
        }

        private Queue<string> _contentQueue;
        #endregion

        #region Constructors
        private ScreenSaverForm()
        {
            InitializeComponent();

            this._contentQueue = new Queue<string>();

            this.InitializeTimer();
        }
        #endregion

        #region Public Methods
        #endregion

        #region Internal Methods
        #endregion

        #region Protected Methods
        #endregion

        #region Private Methods
        /// <summary>
        /// Initialize timer.
        /// </summary>
        private void InitializeTimer()
        {
            this._contentTimer = new Timer() { Interval = 60000 };
            this._contentTimer.Tick += new EventHandler(this.ContentTimer_Tick);
            this._contentTimer.Start();

            this._presentationTimer = new Timer() { Interval = 3000 };
            this._presentationTimer.Tick += new EventHandler(PresentationTimer_Tick);
            this._presentationTimer.Start();
        }

        /// <summary>
        /// Produce content of mini blog.
        /// </summary>
        private void ProduceMiniBlogContent()
        {
            try
            {
                lock (this._contentQueue)
                {
                    if (this._contentQueue.Count > 1000)
                    {
                        this._contentQueue.Clear();
                    }

                    if (this._presentationTime++ >= 9)
                    {
                        this.contentTextBox.Clear();

                        this._presentationTime = 0;

                        this.PresentAdvertisment();
                    }

                    string url = "http://api.t.sina.com.cn/statuses/public_timeline.xml?source=3492837712";

                    HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
                    HttpWebResponse response = request.GetResponse() as HttpWebResponse;
                    string screenName = String.Empty;
                    string content = String.Empty;

                    using (StreamReader reader = new StreamReader(response.GetResponseStream()))
                    {
                        string responseContent = reader.ReadToEnd();

                        XmlDocument document = new XmlDocument();
                        document.LoadXml(responseContent);

                        XmlNodeList statuses = document.GetElementsByTagName("status");

                        foreach (XmlElement statusElement in statuses)
                        {
                            screenName = statusElement.GetElementsByTagName("screen_name")[0].InnerText;
                            content = statusElement.GetElementsByTagName("text")[0].InnerText;

                            this._contentQueue.Enqueue(String.Format(CultureInfo.CurrentUICulture, "{0}: {1}\n", screenName, content));
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                this.contentTextBox.AppendText(ex.Message + "\n");
            }
        }

        /// <summary>
        /// Present single line of content of mini blog.
        /// </summary>
        private void PresentContentLine()
        {
            lock (this._contentQueue)
            {
                if (this._contentQueue.Count == 0)
                {
                    return;
                }

                string line = this._contentQueue.Dequeue();

                if (String.IsNullOrEmpty(line))
                {
                    return;
                }

                int maxValue = 3000 / line.Length;

                foreach (char character in line)
                {
                    this.contentTextBox.SelectionStart = this.contentTextBox.Text.Length;
                    this.contentTextBox.SelectedText = character.ToString();

                    System.Threading.Thread.Sleep(new Random().Next(1, maxValue));
                }

                this.contentTextBox.AppendText("\n");
            }
        }

        /// <summary>
        /// Present advertisment.
        /// </summary>
        private void PresentAdvertisment()
        {
            this.contentTextBox.AppendText(String.Format(CultureInfo.InvariantCulture, "{0} {1} V{2} - {3}\n", CompanyName, ProductName, ProductVersion, global::Autumoon.OpenSource.TScreenSaver.Forms.Properties.Resources.Homepage));
            this.contentTextBox.AppendText("\n");
        }
        #endregion

        #region Delegates and Events
        private void ContentTimer_Tick(object sender, EventArgs e)
        {
            this.ProduceMiniBlogContent();
        }

        private void PresentationTimer_Tick(object sender, EventArgs e)
        {
            this._presentationTimer.Interval = new Random().Next(1, 5000);

            this.PresentContentLine();
        }

        private void ScreenSaverForm_Load(object sender, EventArgs e)
        {
            this.PresentAdvertisment();
            this.ProduceMiniBlogContent();
        }

        private void contentTextBox_KeyDown(object sender, KeyEventArgs e)
        {
            this.Close();
        }

        private void contentTextBox_MouseClick(object sender, MouseEventArgs e)
        {
            this.Close();
        }

        private void contentTextBox_MouseMove(object sender, MouseEventArgs e)
        {
            //this.Close();
        }
        #endregion
    }
}